package com.cnswhy.cloud.server.app.config;
import com.cnswhy.cloud.server.app.utils.ConfigProperties;
import com.cnswhy.cloud.server.app.utils.HttpUtils;
import com.cnswhy.cloud.server.app.utils.HttpsRequest;
import com.cnswhy.cloud.server.app.utils.MD5;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

@Slf4j
public class WxPayApi {
	
	
	/**
     * 
     * 统一下单
     * @param  data 提交给统一下单API的参数
     * @param  key 超时时间
     * @throws Exception
     * @return 成功时返回，其他抛异常
     */
     public static WxPayData UnifiedOrder(WxPayData data, String key) throws Exception
     {
//    	 String total_fee = data.GetValue("total_fee").toString();
//    	 JsApiPay jsApiPay = new JsApiPay(data.GetValue("openid").toString(),Integer.parseInt(total_fee));
         //检测必填参数
         if (data.GetValue("out_trade_no") == null)
         {
             throw new Exception("缺少统一支付接口必填参数out_trade_no！");
         }
         else if (data.GetValue("body") == null)
         {
             throw new Exception("缺少统一支付接口必填参数body！");
         }
         else if (data.GetValue("total_fee") == null)
         {
             throw new Exception("缺少统一支付接口必填参数total_fee！");
         }
         else if (data.GetValue("trade_type") == null)
         {
             throw new Exception("缺少统一支付接口必填参数trade_type！");
         }

         //关联参数
         if (data.GetValue("trade_type").toString() == "JSAPI" && data.GetValue("openid") == null)
         {
             throw new Exception("统一支付接口中，缺少必填参数openid！trade_type为JSAPI时，openid为必填参数！");
         }
         if (data.GetValue("trade_type").toString() == "NATIVE" && data.GetValue("product_id") == null)
         {
             throw new Exception("统一支付接口中，缺少必填参数product_id！trade_type为JSAPI时，product_id为必填参数！");
         }
         //data.SetValue("spbill_create_ip", "8.8.8.8");//终端ip
         UUID uuid = UUID.randomUUID();
         data.SetValue("nonce_str", uuid.toString().replace("-", ""));//随机字符串
         
         //签名
         data.SetValue("sign", WxSignUtils.createSign(data.GetData(), key));
         String xml = data.ToXml();


         log.debug("UnfiedOrder request : " + xml);
         String returnData = HttpUtils.sendPost("https://api.mch.weixin.qq.com/pay/unifiedorder", data.GetData());
         log.error("UnfiedOrder response : " + returnData);

         data.FromXml(returnData);

         return data;
     }
     
     /**
      * 
      * @author Tan Chong
      * @Decoration 查询订单
      * @date 2017-1-6
      * @param  data 提交给查询订单API的参数
      * @return
      * @throws Exception
      */
     public static WxPayData OrderQuery(WxPayData data) throws Exception
     {
         String url = "https://api.mch.weixin.qq.com/pay/orderquery";
         //检测必填参数
         if (data.GetValue("out_trade_no") == null && data.GetValue("transaction_id") == null)
         {
             throw new Exception("订单查询接口中，out_trade_no、transaction_id至少填一个！");
         }
         
         data.SetValue("appid", ConfigProperties.getStringValue("APPID"));//公众账号ID
         data.SetValue("mch_id", ConfigProperties.getStringValue("MCHID"));//商户号
         UUID uuid = UUID.randomUUID();
         data.SetValue("nonce_str", uuid.toString().replace("-", ""));//随机字符串
         data.SetValue("sign", WxSignUtils.createSign(data.GetData(),""));//签名

         String xml = data.ToXml();


         log.debug("OrderQuery request : " + xml);
         HttpsRequest request = new HttpsRequest();
         String returnData = request.sendPost(url, data.GetData());
         log.debug("OrderQuery response : " + returnData);

         //将xml格式的数据转化为对象以返回
         WxPayData result = new WxPayData();
         result.FromXml(returnData);

         return result;
     }
     
     public static String createSign(SortedMap<String,Object> parameters, String key){  
         StringBuffer sb = new StringBuffer();  
         Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序（升序）  
         Iterator it = es.iterator();  
         while(it.hasNext()) {  
             Map.Entry entry = (Map.Entry)it.next();  
             String k = (String)entry.getKey();  
             Object v = entry.getValue();  
             if(null != v && !"".equals(v)   
                     && !"sign".equals(k) && !"key".equals(k)) {  
                 sb.append(k + "=" + v + "&");  
             }  
         }  
         sb.append("key=" + key);
         String sign = MD5.md5s(sb.toString()).toUpperCase();
         return sign;  
     } 
}
